﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;
using projectManagementWeb.Models;
using projectManagementWeb.Models.Admin;
using System.Data.Linq;
using System.Web.UI;

namespace projectManagementWeb.Controllers
{
    public class AccountController : Controller
    {

        #region Fields

        /// <summary>
        /// Connection with Database
        /// </summary>
        private projectmanagementDBDataContext _dbContext;

        #endregion

        //
        // GET: /Account/LogOn

        public ActionResult LogOn()
        {
            return View();
        }

        //
        // POST: /Account/LogOn

        [HttpPost]
        public ActionResult LogOn(LogOnModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                if (Membership.ValidateUser(model.UserName, model.Password))

                //projectmanagementDBDataContext pmwDB = new projectmanagementDBDataContext();
                //var user = pmwDB.spAccesar(model.UserName, model.Password).Single().Result;
                
                //if ( user == 1 )
                {
                    FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
                    if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
                        && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
                    {
                        //if (!Page.IsPostBack) {
                            if (Request.IsAuthenticated && !string.IsNullOrEmpty(Request.QueryString["ReturnUrl"])) // This is an unauthorized, authenticated request... 
                                //Response.Redirect("~/UnauthorizedAccess.aspx");
                            return RedirectToAction("UnauthorizedAccess", "Account");
                        //}

                        return Redirect(returnUrl);
                    }
                    else
                    {
                        return RedirectToAction("Index", "Home");
                    }
                }
                else
                {
                    ModelState.AddModelError("", "Usuario o contraseña incorrectos.");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        //
        // GET: /Account/LogOff

        public ActionResult LogOff()
        {
            FormsAuthentication.SignOut();

            return RedirectToAction("Index", "Home");
        }

        //
        //GET: /Acount/ForgotPassword

        public ActionResult UnauthorizedAccess()
        {
            return View();
        }

        public ActionResult ForgotPassword()
        {
            try
            {
                if (!Membership.EnablePasswordReset) throw new Exception("Password reset is not allowed");
                return View();
            }
            catch (Exception )
            {
                return RedirectToAction("Error", "Shared");
            }
        }

        //
        // POST: /Account/ForgotPassword
        [HttpPost]
        public ActionResult ForgotPassword(ForgotPasswordModel model, string userName)
        {
            
                //Membership.FindUsersByName(ModelState["UserName"].Value.AttemptedValue);

            //foreach (MembershipUser User in UserEmail)
            //{
            //    ModelState["Email"].Value = User.Email;
            //}

            try
            {


                if (ModelState.IsValid)
                {
                    //Get User information
                    MembershipUser Usr = Membership.GetUser(userName);

                    if (Usr.PasswordQuestion == ModelState["Question"].Value.AttemptedValue)
                    {
                        string password = string.Empty;
                        password = Usr.GetPassword(ModelState["Answer"].Value.AttemptedValue);
                        return RedirectToAction("ChangePassword", "Account", new {CurrentUser = userName});
                    }
                }
            }
            catch (Exception ex)
            {
                ModelState.AddModelError(ex.Source, ex.Message);
            }
            // If we got this far, something failed, redisplay form
            return View(model);
        }


        //
        // GET: /Account/Register

        public ActionResult Register()
        {
            return View(new RegisterModel());
        }

        //
        // POST: /Account/Register

        [HttpPost]
        public ActionResult Register(RegisterModel model)
        {
            if (ModelState.IsValid)
            {
                // Attempt to register the user
                MembershipCreateStatus createStatus;
                Membership.CreateUser(model.UserName+"|"+ model.FirstName + "|" + model.LastName, model.Password, model.Email, model.Question, model.Answer, true, null, out createStatus);

                if (createStatus == MembershipCreateStatus.Success)
                {
                    
                    Roles.AddUserToRole(model.UserName, model.Rol);
                    //FormsAuthentication.SetAuthCookie(model.UserName, false /* createPersistentCookie */);
                    return RedirectToAction("AdminAccounts", "Admin");
                }
                else
                {
                    ModelState.AddModelError("", ErrorCodeToString(createStatus));
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        public ActionResult ChangePassword(string UserName)
        {
            var UserNameCurrent = new ChangePasswordModel { UserName = UserName };
            return View(UserNameCurrent);
        }

        [HttpPost]
        public ActionResult ChangePassword(ChangePasswordModel model, string UserName)
        {
            if (ModelState.IsValid)
            {

                // ChangePassword will throw an exception rather
                // than return false in certain failure scenarios.
                bool changePasswordSucceeded;
                try
                {
                    if (User.Identity.Name != string.Empty)
                    {
                        MembershipUser currentUser = Membership.GetUser(User.Identity.Name, true /* userIsOnline */);
                        changePasswordSucceeded = currentUser.ChangePassword(model.OldPassword, model.NewPassword);
                    }
                    else
                    {
                        MembershipUser currentUser = Membership.GetUser(User.Identity.Name, true /* userIsOnline */);
                        changePasswordSucceeded = currentUser.ChangePassword(model.OldPassword, model.NewPassword);
                    }
                    
                }
                catch (Exception)
                {
                    changePasswordSucceeded = false;
                }

                if (changePasswordSucceeded)
                {
                    return RedirectToAction("ChangePasswordSuccess");
                }
                else
                {
                    ModelState.AddModelError("", "The current password is incorrect or the new password is invalid.");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        //
        // GET: /Account/ChangePassword

        [Authorize]
        public ActionResult ChangePasswordLogged()
        {
            return View();
        }

        //
        // POST: /Account/ChangePassword
        [Authorize]
        [HttpPost]
        public ActionResult ChangePasswordLogged(ChangePasswordModel model)
        {
            if (ModelState.IsValid)
            {

                // ChangePassword will throw an exception rather
                // than return false in certain failure scenarios.
                bool changePasswordSucceeded;
                try
                {
                    MembershipUser currentUser = Membership.GetUser(User.Identity.Name, true /* userIsOnline */);
                    changePasswordSucceeded = currentUser.ChangePassword(model.OldPassword, model.NewPassword);
                }
                catch (Exception)
                {
                    changePasswordSucceeded = false;
                }

                if (changePasswordSucceeded)
                {
                    return RedirectToAction("ChangePasswordSuccess");
                }
                else
                {
                    ModelState.AddModelError("", "The current password is incorrect or the new password is invalid.");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        //
        // GET: /Account/ChangePasswordSuccess

        public ActionResult ChangePasswordSuccess()
        {
            return View();
        }

        /// <summary>
        /// Constructor
        /// </summary>
        public AccountController()
        {
            Init();
        }

        /// <summary>
        /// Placeholder method to connect to the database
        /// </summary>
        private void Init()
        {
            try
            {
                _dbContext = new projectmanagementDBDataContext();
            }
            catch (Exception)
            {
                return;
            }
        }

        public UserDataModel GetUserData(string username)
        {
            UserDataModel user = new UserDataModel();

            ISingleResult<aspnet_User> resultUser = _dbContext.spGetUser(username);
            foreach (aspnet_User userResult in resultUser)
            {
                user.UserCompleteName = userResult.FirstName + " " + userResult.LastName;
                user.FirstName = userResult.FirstName;
                user.LastName = userResult.LastName;
                user.UserName = username;
                
            }


            ISingleResult<aspnet_Membership> result = _dbContext.spGetUserMembership(username);
            foreach (aspnet_Membership userResult in result)
            {
                user.Question = userResult.PasswordQuestion;
                user.Answer = userResult.PasswordAnswer;
                user.Password = userResult.Password;
            }

            return user;
        }

        #region Status Codes
        private static string ErrorCodeToString(MembershipCreateStatus createStatus)
        {
            // See http://go.microsoft.com/fwlink/?LinkID=177550 for
            // a full list of status codes.
            switch (createStatus)
            {
                case MembershipCreateStatus.DuplicateUserName:
                    return "El nombre de usuario ya existe. Por favor ingrese un nombre de usuario diferente";
                    //return "User name already exists. Please enter a different user name.";

                case MembershipCreateStatus.DuplicateEmail:
                    return "Ya existe un nombre de usuario para ese email. Por favor ingrese un email diferente.";
                    //return "A user name for that e-mail address already exists. Please enter a different e-mail address.";

                case MembershipCreateStatus.InvalidPassword:
                    return "La contraseña proporcionada es invalida. Por favor ingrese una contraseña valida";
                    //return "The password provided is invalid. Please enter a valid password value.";

                case MembershipCreateStatus.InvalidEmail:
                    return "El email proporcionado es invalido. Pro favor ingrese un email valido.";
                    //return "The e-mail address provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidAnswer:
                    return "La respuesta para la recuperacion de la contraseña es invalida. Por favor reviselo e intentelo de nuevo.";
                    //return "The password retrieval answer provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidQuestion:
                    return "La pregunta para la recuperacion de la contraseña es invalida. Por favor revisela e intentelo de nuevo.";
                    //return "The password retrieval question provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidUserName:
                    return "EL nombre de usuario es invalido. Por favor cambielo e intentelo de nuevo.";
                    //return "The user name provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.ProviderError:
                    return "Ha ocurrido un erro interno de la aplicacion por favor contacte al administrador del sistema";
                    //return "The authentication provider returned an error. Please verify your entry and try again. If the problem persists, please contact your system administrator.";

                case MembershipCreateStatus.UserRejected:
                    return "La peticion de creacion del usuario ha sido cancelada. Por favor verifique los datos e intente de nuevo. Si el problema persiste contacte al administrador del sistema.";
                    //return "The user creation request has been canceled. Please verify your entry and try again. If the problem persists, please contact your system administrator.";

                default:
                    return "Ha ocurrido un error desconocido. Por favor intente de nuevo, si el problema presiste contacte al administrador del sistema.";
                    //return "An unknown error occurred. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
            }
        }
        #endregion
    }
}
